package xiongwei.jiang.service;

import com.google.common.collect.Multimap;
import xiongwei.jiang.model.dto.*;
import xiongwei.jiang.service.impl.WXWorkServiceImpl;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * 企业微信服务接口
 *
 * @author 天之蓝
 */
public interface WXWorkService {
    /**
     * 获取工号
     *
     * @param appIndex 索引
     * @param code     企业微信返回一次性 code，5 分钟内有效
     * @return 对象
     * @author 天之蓝
     */
    UserIdResponseDTO getUserId(Integer appIndex, String code);

    /**
     * 获取 user 信息
     *
     * @param appIndex 索引
     * @param userId   工号
     * @return 对象
     * @author 天之蓝
     */
    UserInfoResponseDTO getUserInfo(Integer appIndex, String userId);

    /**
     * 获取 department 部门列表
     *
     * @param appIndex     索引
     * @param departmentId 部门 id，获取指定部门及其下的子部门（以及及子部门的子部门等等，递归），如果不填，默认获取全量组织架构
     * @return 对象
     * @author 天之蓝
     */
    DepartmentDataResponseDTO getDepartmentData(Integer appIndex, Integer departmentId);

    /**
     * 获取 department 部门 user 简单信息
     *
     * @param appIndex     索引
     * @param departmentId 部门 id
     * @param fetchChild   是否递归获取子部门下面的成员（1-递归获取，0-只获取本部门）
     * @return 对象
     * @author 天之蓝
     */
    DepartmentUserResponseDTO getDepartmentUser(Integer appIndex, Integer departmentId, Integer fetchChild);

    /**
     * 获取 tag 标签列表（token 必须由通讯录 secret 获取）
     *
     * @return 对象
     * @author 天之蓝
     */
    TagDataResponseDTO getTagData();

    /**
     * 获取 tag 标签 user 简单信息（token 必须由通讯录 secret 获取）
     *
     * @param tagId 标签 id
     * @return 对象
     * @author 天之蓝
     */
    TagUserResponseDTO getTagUser(Integer tagId);

    /**
     * 发送文本信息
     *
     * @param appIndex 索引
     * @param userId   工号（多个工号之间用“|”隔开，不允许加空格）
     * @param content  文本内容
     * @return 对象
     * @author 天之蓝
     */
    AppMsgResponseDTO sendTextMsg(Integer appIndex, String userId, String content);

    /**
     * 发送文本信息
     *
     * @param appIndex   索引
     * @param userIdList 工号集合
     * @param content    文本内容
     * @return 对象
     * @author 天之蓝
     */
    AppMsgResponseDTO sendTextMsg(Integer appIndex, List<String> userIdList, String content);

    /**
     * 上传临时素材
     *
     * @param appIndex 索引
     * @param typeEnum 临时素材类型
     * @param filePath 临时素材绝对路径
     * @return 对象
     * @throws IOException 异常
     * @author 天之蓝
     */
    UploadTempResponseDTO uploadTemp(Integer appIndex, WXWorkServiceImpl.UploadTypeEnum typeEnum, String filePath) throws IOException;

    /**
     * 上传图片
     *
     * @param appIndex 索引
     * @param filePath 图片绝对路径
     * @return 对象
     * @throws IOException 异常
     * @author 天之蓝
     */
    UploadImageResponseDTO uploadImage(Integer appIndex, String filePath) throws IOException;

    /**
     * 获取临时素材
     *
     * @param appIndex 索引
     * @param mediaId  媒体文件 id
     * @return 字节数组
     * @author 天之蓝
     */
    byte[] downloadTemp(Integer appIndex, String mediaId);

    /**
     * 获取高清语音素材
     *
     * @param appIndex 索引
     * @param mediaId  媒体文件 id
     * @return 字节数组
     * @author 天之蓝
     */
    byte[] downloadVoice(Integer appIndex, String mediaId);

    /**
     * 获取打卡信息（token 必须由打卡 secret 获取）
     *
     * @param openCheckinDataType 打卡类型（1-上下班打卡，2-外出打卡，3-全部打卡）
     * @param startTime           获取打卡记录的开始时间（10 位 Unix 时间戳）
     * @param endTime             获取打卡记录的结束时间（10 位 Unix 时间戳）
     * @param userIdList          工号集合（至多 100 个）
     * @return 对象
     * @author 天之蓝
     */
    CheckinDataResponseDTO getCheckinData(Integer openCheckinDataType, Long startTime, Long endTime, List<String> userIdList);

    /**
     * 获取 token 缓存
     *
     * @param appIndex 索引
     * @return token
     * @author 天之蓝
     */
    String getTokenCache(Integer appIndex);

    /**
     * 获取 jsapi_ticket 缓存
     *
     * @param appIndex 索引
     * @return JsapiTicket
     * @author 天之蓝
     */
    String getJsapiTicketCache(Integer appIndex);

    /**
     * 获取 jsapi_ticket_agent 缓存
     *
     * @param appIndex 索引
     * @return JsapiTicketAgent
     * @author 天之蓝
     */
    String getJsapiTicketAgentCache(Integer appIndex);

    /**
     * 验证 url
     *
     * @param appIndex      索引
     * @param msg_signature 企业微信加密签名，msg_signature计算结合了企业填写的token、请求中的timestamp、nonce、加密的消息体
     * @param timestamp     时间戳（与nonce结合使用，用于防止请求重放攻击）
     * @param nonce         随机数（与timestamp结合使用，用于防止请求重放攻击）
     * @param echostr       加密的字符串（需要解密得到消息内容明文，解密后有random、msg_len、msg、receiveid四个字段，其中msg即为消息内容明文）
     * @param response      响应
     * @return true-成功，false-失败
     * @author 天之蓝
     */
    boolean verifyUrl(Integer appIndex, String msg_signature, String timestamp, String nonce, String echostr, HttpServletResponse response);

    /**
     * 处理 callback
     *
     * @param appIndex      索引
     * @param msg_signature 企业微信加密签名，msg_signature结合了企业填写的token、请求中的timestamp、nonce参数、加密的消息体
     * @param timestamp     时间戳（与nonce结合使用，用于防止请求重放攻击）
     * @param nonce         随机数（与timestamp结合使用，用于防止请求重放攻击）
     * @param xml           回调数据（放在 HTTP 请求体中，使用 @RequestBody 注解接收）
     * @param response      响应
     * @return k-v（LinkedHashMultimap，k 为完全限定节点名称，例如：grandparentNodeName.parentNodeName.nodeName）
     * @author 天之蓝
     */
    Multimap<String, String> callback(Integer appIndex, String msg_signature, String timestamp, String nonce, String xml, HttpServletResponse response);

    /**
     * 获取 config 签名
     *
     * @param appIndex       索引
     * @param currentPageUrl 当前页面 url
     * @return 对象
     * @author 天之蓝
     */
    ConfigSignatureResponseDTO getConfigSignature(Integer appIndex, String currentPageUrl);

    /**
     * 获取 agentConfig 签名
     *
     * @param appIndex       索引
     * @param currentPageUrl 当前页面 url
     * @return 对象
     * @author 天之蓝
     */
    AgentConfigSignatureResponseDTO getAgentConfigSignature(Integer appIndex, String currentPageUrl);

    /**
     * 获取企业微信服务器的 ip 段
     *
     * @param appIndex 索引
     * @return 对象
     * @author 天之蓝
     */
    CallbackIpResponseDTO getCallbackIp(Integer appIndex);
}
